<template>
  <div class="i-quill" :class="classes">
    <div id="toolbar-container" style="display:none">
      <span class="ql-formats">
        <select class="ql-font"></select>
        <select class="ql-size"></select>
      </span>
      <span class="ql-formats">
        <button class="ql-bold"></button>
        <button class="ql-italic"></button>
        <button class="ql-underline"></button>
        <button class="ql-strike"></button>
      </span>
      <span class="ql-formats">
        <select class="ql-color"></select>
        <select class="ql-background"></select>
      </span>
      <span class="ql-formats">
        <button class="ql-header header6" value="1"></button>
        <button class="ql-header header6" value="2"></button>
        <button class="ql-header header6" value="3">3</button>
        <button class="ql-header header6" value="4">4</button>
        <button class="ql-header header6" value="5">5</button>
        <button class="ql-header header6" value="6">6</button>
      </span>
      <span class="ql-formats">
        <button class="ql-script" value="sub"></button>
        <button class="ql-script" value="super"></button>
      </span>
      <span class="ql-formats">
        <button class="ql-blockquote"></button>
        <button class="ql-code-block"></button>
      </span>
      <span class="ql-formats">
        <button class="ql-list" value="ordered"></button>
        <button class="ql-list" value="bullet"></button>
        <button class="ql-indent" value="-1"></button>
        <button class="ql-indent" value="+1"></button>
      </span>
      <span class="ql-formats">
        <button class="ql-direction" value="rtl"></button>
        <select class="ql-align"></select>
      </span>
      <span class="ql-formats">
        <button class="ql-link"></button>
        <button class="ql-image"></button>
        <button class="ql-video"></button>
        <button class="ql-formula"></button>
      </span>
      <span class="ql-formats">
        <button class="ql-clean"></button>
      </span>
    </div>
    <div ref="editor" :style="styles"></div>
    <videoDialog
      ref="video"
      :name="name"
      :limit="limit"
      :show-upload-list="showUploadList"
      :type="type"
      :on-error="onError"
      :field-id="fieldId"
      :field-data="fieldData"
      :field-path="fieldPath"
      :with-credentials="withCredentials"
      :maxSize="maxSize"
      :headers="headers"
      :mask-closable="maskClosable"
      :action="action"
      @emitVideoInfo="handleObtainVideo"
    ></videoDialog>
  </div>
</template>

<script>
import Quill from "quill";
import { size, fonts } from "./custom/register.js";
import * as register from "./custom/register.js";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
const videoDialog = () => import("./dialog");
export default {
  name: "Quill",
  props: {
    withCredentials: {},
    name: {},
    maskClosable: {},
    action: {},
    showUploadList: {
      default: true
    },
    limit: {},
    format: {
      default() {
        return [];
      }
    },
    type: {},
    headers: {},
    maxSize: {},
    onError: {},
    fieldData: {},
    fieldPath: {},
    fieldId: {},
    value: {
      type: String,
      default: "hello world!"
    },
    border: {
      type: Boolean,
      default: false
    },
    height: {
      type: Number,
      default: 500
    },
    minHeight: {
      type: Number,
      default: 300
    }
  },
  data() {
    return {
      Quill: null,
      currentValue: "",
      options: {
        theme: "snow",
        bounds: document.body,
        debug: "warn",
        modules: {
          //toolbar: '#toolbar-container'
          toolbar: [
            ["bold", "italic", "underline", "strike"],
            [{ header: [1, 2, 3, 4, 5, 6, false] }],
            [{ size: size() }],
            [{ color: [] }, { background: [] }],
            ["blockquote", "code-block"],
            [{ list: "ordered" }, { list: "bullet" }],
            [{ script: "sub" }, { script: "super" }],
            [{ header: "1" }, { header: "2" }],
            [{ indent: "-1" }, { indent: "+1" }],
            [{ align: [] }],
            [{ direction: "rtl" }],
            [{ font: fonts() }],
            ["clean"],
            ["link", "image", "video"]
          ]
        },
        placeholder: "内容...",
        readOnly: false
      }
    };
  },
  components: {
    videoDialog
  },
  computed: {
    classes() {
      return [
        {
          "i-quill-no-border": !this.border
        }
      ];
    },
    styles() {
      let style = {};
      if (this.minHeight) {
        style.minHeight = `${this.minHeight}px`;
      }
      if (this.height) {
        style.height = `${this.height}px`;
      }
      return style;
    }
  },
  watch: {
    value: {
      handler(val) {
        if (val !== this.currentValue) {
          this.currentValue = val;
          if (this.Quill) {
            this.Quill.pasteHTML(this.value);
          }
        }
      },
      immediate: true
    }
  },
  methods: {
    init() {
      const editor = this.$refs.editor;
      // 初始化编辑器
      this.Quill = new Quill(editor, this.options);
      // 默认值
      this.Quill.pasteHTML(this.currentValue);
      // 绑定事件
      this.Quill.on("text-change", (delta, oldDelta, source) => {
        const html = this.$refs.editor.children[0].innerHTML;
        const text = this.Quill.getText();
        const quill = this.Quill;
        // 更新内部的值
        this.currentValue = html;
        // 发出事件 v-model
        this.$emit("input", html);
        // 发出事件
        this.$emit("on-change", { html, text, quill });
      });
      // 将一些 quill 自带的事件传递出去
      this.Quill.on("text-change", (delta, oldDelta, source) => {
        this.$emit("on-text-change", { delta, oldDelta, source });
      });
      this.Quill.on("selection-change", (range, oldRange, source) => {
        this.$emit("on-selection-change", { range, oldRange, source });
      });
      this.Quill.on("editor-change", (eventName, ...args) => {
        this.$emit("on-editor-change", eventName, ...args);
      });
    },
    handleObtainVideo(val = []) {
      var range = this.Quill.getSelection();
      //视频插入在富文本中的位置
      var index = 0;
      if (range == null) {
        index = 0;
      } else {
        index = range.index;
      }
      this.$emit("on-upload-change", { val });
      //将视频链接插入到当前的富文本当中
      val.map(({ path }) => {
        this.Quill.insertEmbed(index, "video", path);
      });
    },
    handlerFormat() {
      const toolbar = this.Quill.getModule("toolbar");
      toolbar.addHandler("video", () => {
        this.$refs.video.init();
      });
    }
  },
  mounted() {
    this.init();
    this.handlerFormat();
  },
  beforeDestroy() {
    // 在组件销毁后销毁实例
    this.Quill = null;
  }
};
</script>

<style lang="less">
@import "./custom/size.less";
@import "./custom/header.less";
@import "./custom/font.less";
.i-quill .ql-editor .ql-video{
  margin:4px auto;
  width:400px;
}
.i-quill-no-border {
  .ql-toolbar.ql-snow {
    border: none;
    border-bottom: 1px solid #e8eaec;
  }
  .ql-container.ql-snow {
    border: none;
  }
}
</style>
